#include "PreCompile.hpp"
#include "SuperGlobTests.hpp"
#include "../SuperGlob.hpp"
#include "TestDirTree.hpp"

namespace BuildNG
{
  void SuperGlobTests::test_tokenize_glob_pattern()
  {
    {
      TmpArray<GlobToken> tokens;
      tokenize_glob_pattern("*foo*",tokens);
      assert(tokens.get_size() == 3);
      assert(tokens[0] == "*");
      assert(tokens[0].is_wildcard == true);
      assert(tokens[1] == "foo");
      assert(tokens[1].is_wildcard == false);
      assert(tokens[2] == "*");
      assert(tokens[2].is_wildcard == true);
    }

    {
      TmpArray<GlobToken> tokens;
      tokenize_glob_pattern("foo",tokens);
      assert(tokens.get_size() == 1);
      assert(tokens[0] == "foo");
      assert(tokens[0].is_wildcard == false);
    }

    {
      TmpArray<GlobToken> tokens;
      tokenize_glob_pattern("foo*bar",tokens);
      assert(tokens.get_size() == 3);
      assert(tokens[0] == "foo");
      assert(tokens[0].is_wildcard == false);
      assert(tokens[1] == "*");
      assert(tokens[1].is_wildcard == true);
      assert(tokens[2] == "bar");
      assert(tokens[2].is_wildcard == false);
    }

    {
      TmpArray<GlobToken> tokens;
      tokenize_glob_pattern("foo.....bar",tokens);
      assert(tokens.get_size() == 3);
      assert(tokens[0] == "foo");
      assert(tokens[0].is_wildcard == false);
      assert(tokens[1] == "...");
      assert(tokens[1].is_wildcard == true);
      assert(tokens[2] == "..bar");
      assert(tokens[2].is_wildcard == false);
    }

    {
      TmpArray<GlobToken> tokens;
      tokenize_glob_pattern("??*?**",tokens);
      assert(tokens.get_size() == 6);
      assert(tokens[0] == "?");
      assert(tokens[1] == "?");
      assert(tokens[2] == "*");
      assert(tokens[3] == "?");
      assert(tokens[4] == "*");
      assert(tokens[5] == "*");
    }
  }

  void SuperGlobTests::test_glob_compare()
  {
    assert(glob_compare("foobar","foobar"));
    assert(glob_compare("*","foobar"));
    assert(!glob_compare("?????","foobar"));
    assert(glob_compare("??????","foobar"));
    assert(!glob_compare("?*",""));
    assert(glob_compare("*",""));
    assert(glob_compare("abc*def*ghi?j","abcdef123ghi1j"));
    assert(!glob_compare("abc?*def*ghi?j","abcdef123ghi1j"));
    assert(glob_compare("ba*laa?p","baalaalaaip"));
  }

  bool vec_contains(const std::vector<Glib::ustring> &vec,const Glib::ustring &str)
  {
    for(int i = 0;i < (int)vec.size();i++)
      if(vec[i] == str)
        return true;
    return false;
  }

  void SuperGlobTests::test_glob_with_fake_tree()
  {
    TestDirectoryTree test_dir_tree("TestData/DirTree.xml");
    
    {
      // relative path's result must also be relative
      std::vector<Glib::ustring> res = super_glob("*",test_dir_tree);
      assert(res.size() == 1);
      assert(res[0] == "folder1");
    }

    {
      // absolute path's result must also be absolute
      std::vector<Glib::ustring> res = super_glob("/*",test_dir_tree);
      assert(res.size() == 1);
      assert(res[0] == "/folder1");
    }

    {
      std::vector<Glib::ustring> res = super_glob("/folder1/folder2/*.cpp",test_dir_tree);
      assert(res.size() == 1);
      assert(res[0] == "/folder1/folder2/SuperGlob.cpp");
    }

    {
      std::vector<Glib::ustring> res = super_glob("/folder1/folder2/*/*.cpp",test_dir_tree);
      assert(res.size() == 2);
      assert(vec_contains(res,"/folder1/folder2/folder3/SuperGlob.cpp"));
      assert(vec_contains(res,"/folder1/folder2/folder1/SuperGlob.cpp"));
    }

    {
      std::vector<Glib::ustring> res = super_glob("/folder1/folder2/*/*.*",test_dir_tree);
      assert(res.size() == 4);
      assert(vec_contains(res,"/folder1/folder2/folder3/SuperGlob.cpp"));
      assert(vec_contains(res,"/folder1/folder2/folder1/SuperGlob.cpp"));
      assert(vec_contains(res,"/folder1/folder2/folder3/SuperGlob.h"));
      assert(vec_contains(res,"/folder1/folder2/folder1/SuperGlob.h"));
    }

    {
      std::vector<Glib::ustring> res = super_glob("/folder1/folder2/*/*.?",test_dir_tree);
      assert(res.size() == 2);
      assert(vec_contains(res,"/folder1/folder2/folder3/SuperGlob.h"));
      assert(vec_contains(res,"/folder1/folder2/folder1/SuperGlob.h"));
    }

    {
      std::vector<Glib::ustring> res = super_glob("/*/folder1",test_dir_tree);
      assert(res.size() == 1);
      assert(vec_contains(res,"/folder1/folder1"));
    }
  }
}

